
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fs::File;
use std::path::Path; // 添加 Path 的导入
use std::sync::Mutex;
use std::io::Read;
use tauri::State;
use tauri_plugin_dialog::DialogExt;

use log::{error, info};
//use regex::Regex;
use zip::ZipArchive;

// 定义应用程序的状态
struct AppState {
    logs: HashMap<String, Vec<u8>>, // 存储日志名和内容
    current_zip: Option<String>, // 当前打开的 ZIP 文件路径
}

#[derive(Serialize)]
struct LogsResponse {
    logs: HashMap<String, LogDisplay>,
}

#[derive(Serialize)]
struct LogDisplay {
    html: String,
}

/// 将 HashMap<String, Vec<u8>> 转换为 LogsResponse  
fn convert_map(input_map: HashMap<String, Vec<u8>>) ->  Option<LogsResponse>  {  
    let mut output_logs = HashMap::new();  

    for (key, value) in input_map {  
        match String::from_utf8(value) {  
            Ok(html_string) => {  
                // 创建 LogDisplay 实例  
                let log_display = LogDisplay { html: html_string };  
                // 插入到新的 HashMap 中  
                output_logs.insert(key, log_display);  
            }  
            Err(_) => {  
                // 如果转换失败，返回 None  
                return None;  
            }  
        }  
    }  

    Some(LogsResponse { logs: output_logs }) 
} 



#[tauri::command]
fn open_zip(state: State<Mutex<AppState>>, app_handle: tauri::AppHandle) -> Option<String> {
    let file_path = app_handle.dialog()
        .file()
        .add_filter("ZIP Archives", &["zip"]) // 添加文件过滤条件  
        .blocking_pick_file();


    if let Some(path_str) = file_path {  
        // 确保将 `FilePath` 转换为 `String`  
        let path_as_string = path_str.to_string();  

        // 创建路径对象  
        let path = Path::new(&path_as_string);  
        
        // 尝试打开文件  
        match File::open(path) {  
            Ok(file) => {  
                // 创建 ZIP 归档对象  
                let mut archive = match ZipArchive::new(file) {  
                    Ok(archive) => archive,  
                    Err(_) => {  
                        error!("Failed to read zip archive: {}", path_as_string);  
                        return None;  
                    }  
                };  

                let mut logs = HashMap::new();  

                // 遍历 ZIP 中的文件  
                for i in 0..archive.len() {  
                    if let Ok(mut file) = archive.by_index(i) {  
                        if file.is_file() {  
                            let mut contents = Vec::new();  
                            if file.read_to_end(&mut contents).is_ok() {  
                                logs.insert(file.name().to_string(), contents);  
                            }  
                        }  
                    }  
                }  

                // 更新状态  
                let mut app_state = state.lock().unwrap();  
                app_state.logs = logs;  
                app_state.current_zip = Some(path_as_string.clone());  

                info!("Successfully opened zip file: {}", path_as_string);  
                return Some(path_as_string); // 确保返回 `String`  
            }  
            Err(_) => {  
                error!("Failed to open zip file: {}", path_as_string);  
            }  
        }  
    }  
    None
}


#[tauri::command]
fn get_ori_logs(state: State<Mutex<AppState>>) ->  Option<LogsResponse> {
    let app_state = state.lock().unwrap();
    convert_map(app_state.logs.clone())  
}



#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_dialog::init())
        .plugin(tauri_plugin_fs::init())
        .manage(Mutex::new(AppState {
            logs: HashMap::new(),
            current_zip: None,
        }))
        .invoke_handler(tauri::generate_handler![
            open_zip,
            get_ori_logs,
        ])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
